package backend

import (
	models "awesomeProject1/models/pojo"
	modelsServer "awesomeProject1/models/server"
	"awesomeProject1/pkg/e"
	"awesomeProject1/pkg/gintool"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/simplechain-org/client/log"
	"strings"
	"time"
)

type CheckUpDetailsTooEarlyReq struct {
	StartDate string `json:"startDate"` //格式：20230824
	EndDate   string `json:"endDate"`   //格式：20230824
}

//检查转账详情中的行业属性上链太早
func (b *backend) checkUpDetailsTooEarly(ctx *gin.Context) {
	fnName := "checkUpDetailsTooEarly"
	req := new(CheckUpDetailsTooEarlyReq)
	if err := ctx.Bind(req); err != nil {
		log.Error("params validate error:", "err", err.Error())
		gintool.ResultCodeWithData(ctx, e.InvalidParams, err.Error())
		return
	}

	hasEnd, startTime, endTime := parseDateRange(ctx, req.StartDate, req.EndDate)
	if hasEnd {
		return
	}

	//所有的详情上传数据
	allSendDetailsList, hasEnded := b.getAllSendDetailsList(ctx, startTime, endTime)
	if hasEnded {
		return
	}

	//找到所有的行业属性详情上传数据
	transferDetailsVoList, hasEnded := b.getLastDetailsList(ctx, allSendDetailsList)
	if hasEnded {
		return
	}

	wrongCount := 0
	for _, detailsVo := range transferDetailsVoList {
		log.Info(fnName, "正在检查：", detailsVo.ReceiptIDHash)
		//查询这笔详情的账户是否需要继续监控
		isTracedAccount, err := b.loanContractService.IsTracedAccount(detailsVo.Detail.ReceiptIDHash, detailsVo.Detail.AccountNumberHash)
		if err != nil {
			log.Error(fnName, "callFn", "b.loanContractService.IsTracedAccount", "err", err.Error())
			gintool.ResultCodeWithData(ctx, e.CallContractErr, err.Error())
			return
		}
		if !isTracedAccount {
			continue
		}

		//通过借据号哈希查询到此笔借据的放款信息
		firstLoanDetails, count, err := b.detailServ.GetFirstLoanDetailsByReceiptIdHash(detailsVo.Detail.ReceiptIDHash)
		if err != nil {
			log.Error(fnName, "callFn", "b.detailServ.GetFirstLoanDetailsByReceiptIdHash", "err", err.Error())
			gintool.ResultCodeWithData(ctx, e.Error, err.Error())
			return
		}
		if count > 1 {
			log.Warn(fnName, "hint", "通过receiptIdHash查询first_loan表，匹配到了多条数据", "detailsVo.ReceiptIDHash", detailsVo.ReceiptIDHash)
		} else if len(firstLoanDetails) == 0 {
			log.Warn(fnName, "hint", "通过receiptIdHash查询first_loan表，未匹配到数据", "detailsVo.ReceiptIDHash", detailsVo.ReceiptIDHash)
			continue
		}

		loanDateStr := firstLoanDetails[0].LoanDate
		loanDate, err := time.ParseInLocation("20060102", loanDateStr, time.Local)
		if err != nil {
			log.Error(fnName, "callFn", " time.ParseInLocation", "err", err.Error(), "loanDateStr", loanDateStr)
			gintool.ResultCodeWithData(ctx, e.Error, err.Error())
			return
		}
		transferDate, err := time.ParseInLocation("20060102", detailsVo.Detail.Date, time.Local)
		if err != nil {
			log.Error(fnName, "callFn", " time.ParseInLocation", "err", err.Error(), "transferDate", detailsVo.Detail.Date)
			gintool.ResultCodeWithData(ctx, e.Error, err.Error())
			return
		}

		days := transferDate.Sub(loanDate).Hours() / 24
		if days < 15 {
			log.Warn(fnName, "hint", "可能提前调用了行业详情上传接口",
				"detailsVo.ReceiptIDHash", detailsVo.ReceiptIDHash,
				"detailsVo.From", strings.ReplaceAll(detailsVo.From, "map", "FromMap"),
				"detailsVo.To", strings.ReplaceAll(detailsVo.To, "map", "ToMap"),
				"detailsVo.Detail", detailsVo.Detail)
			wrongCount++
		}
	}

	hint := fmt.Sprintln("总共检测行业属性详情上传笔数：", len(transferDetailsVoList), "异常笔数", wrongCount)
	gintool.ResultCodeWithData(ctx, e.Ok, hint)
	gintool.ResultOk(ctx)
}

//获取所有行业属性上链的详情
func (b *backend) getLastDetailsList(ctx *gin.Context, sendDetailsList []models.UploadDetailsRecord) (transferDetailsVoList []modelsServer.TransferDetailsVo, hasEnded bool) {
	fnName := "getLastDetailsList"
	for _, sendDetails := range sendDetailsList {
		transactionDetail := models.TransactionDetail{}
		err := json.Unmarshal([]byte(sendDetails.TransferDetails), &transactionDetail)
		if err != nil {
			hint := "解析对象失败"
			log.Error(fnName, "hint", hint, "detailsRecord", sendDetails)
			gintool.ResultCodeWithData(ctx, e.DeSerializeObjErr, hint)
			hasEnded = true
			return
		}
		if transactionDetail.Detail.CounterpartyAccountHash == "" ||
			transactionDetail.Detail.CounterpartyAccountHash == "1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b" {
			transferDetailsVoList = append(transferDetailsVoList, modelsServer.TransferDetailsVo{
				UploadDetailsRecord: sendDetails,
				TransactionDetail:   transactionDetail,
			})
		}
	}
	return
}
